/*
 * Copyright 2010 - 2011, The PLDesktop Development Team
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 */
#ifndef PLHASH_H
#define PLHASH_H

#include <kernel/lang/PLIHash.h>
#include <kernel/PLGlobal.h>
#ifndef KERNEL
//#include <kernel/PLChar.h>
//#include <tools/PLCharBuffer.h>
#endif

namespace PLSDK {

    /**
     * Generate a hash value for a char.
     *
     * @param key The key to generate the value for.
     * @return The hash value for the key.
     */
    inline pluint plHash(char key) {
        return pluint(key);
    }

    /**
     * Generate a hash value for a unsigned char.
     *
     * @param key The key to generate the value for.
     * @return The hash value for the key.
     */
    inline pluint plHash(pluchar key) {
        return pluint(key);
    }

    /**
     * Generate a hash value for a signed char.
     *
     * @param key The key to generate the value for.
     * @return The hash value for the key.
     */
    inline pluint plHash(signed char key) {
        return pluint(key);
    }

    /**
     * Generate a hash value for a unsigned short.
     *
     * @param key The key to generate the value for.
     * @return The hash value for the key.
     */
    inline pluint plHash(plushort key) {
        return pluint(key);
    }

    /**
     * Generate a hash value for a short.
     *
     * @param key The key to generate the value for.
     * @return The hash value for the key.
     */
    inline pluint plHash(short key) {
        return pluint(key);
    }

    /**
     * Generate a hash value for a unsigned integer.
     *
     * @param key The key to generate the value for.
     * @return The hash value for the key.
     */
    inline pluint plHash(pluint key) {
        return key;
    }

    /**
     * Generate a hash value for a integer.
     *
     * @param key The key to generate the value for.
     * @return The hash value for the key.
     */
    inline pluint plHash(int key) {
        return pluint(key);
    }

    /**
     * Generate a hash value for a unsigned long.
     *
     * @param key The key to generate the value for.
     * @return The hash value for the key.
     */
    PLAPI_EXPORT pluint plHash(plulong key);

    /**
     * Generate a hash value for a long.
     *
     * @param key The key to generate the value for.
     * @return The hash value for the key.
     */
    inline pluint plHash(long key) {
        return plHash(plulong(key));
    }

    /**
     * Generate a hash value for a unsigned 64 bit integer.
     *
     * @param key The key to generate the value for.
     * @return The hash value for the key.
     */
    PLAPI_EXPORT pluint plHash(pluint64 key);

    /**
     * Generate a hash value for a 64 bit integer.
     *
     * @param key The key to generate the value for.
     * @return The hash value for the key.
     */
    inline pluint plHash(plint64 key) {
        return plHash(pluint64(key));
    }

    /**
     * Generate a hash value for a double.
     *
     * @param key The key to generate the value for.
     * @return The hash value for the key.
     */
    inline pluint plHash(double key) {
        return plHash(pluint64(key));
    }

    /**
     * Generate a hash value for a pointer.
     *
     * @param key The key to generate the value for.
     * @return The hash value for the key.
     */
    template <class T>
    inline pluint plHash(const T *key) {
        return pluint(reinterpret_cast<pluint>(key));
    }

    /**
     * These functions are based on Peter J. Weinberger's hash function
     * (from the Dragon Book). The constant 24 in the original function
     * was replaced with 23 to produce fewer collisions on input such as
     * "a", "aa", "aaa", "aaaa", ...
     *
     * @param p The byte array to generate the hash for.
     * @param n The length of the character array.
     * @return The hash value for the key.
     */
    PLAPI_EXPORT pluint plHash(const pluchar *p, pluint n);

#ifndef KERNEL
    /**
     * Generate a hash value for a charbuffer.
     *
     * @param key The key to generate the value for.
     * @return The hash value for the key.
     */
//    PLAPI_EXPORT pluint plHash(PLCharBuffer &key);
#endif

    /**
     * Generate a hash value for a charbuffer.
     *
     * @param key The key to generate the value for.
     * @return The hash value for the key.
     */
    PLAPI_EXPORT pluint plHash(PLIHash &key);

}
    
#endif
